`timescale 1ns / 1ps
`include "defines.v"
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2019/11/09 15:07:42
// Design Name: 
// Module Name: regfile
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module regfile(
    input wire clk,
    input wire rst,
    //写端口
    input wire we,
    input wire[`RegAddrBus] waddr,
    input wire[`RegBus] wdata,
    //读端口1
    input wire re1,
    input wire[`RegAddrBus] raddr1,
    output reg[`RegBus] rdata1,
    //读端口2
    input wire re2,
    input wire[`RegAddrBus] raddr2,
    output reg[`RegBus] rdata2
    );

    //定义32个32 位的寄存器
    reg [`RegBus] regs[0:`RegNum-1];

    //写操作
    always @(posedge clk) begin
        if (rst == `RstDisable) begin
            if ((we == `WriteEnable) && (waddr != `RegNumLog2'h0)) begin
                regs[waddr] <= wdata;
            end
        end
    end

    //读端口1
    always @(*) begin
        if ((rst == `RstEnable) || (re1 != `ReadEnable) || (raddr1 == `RegNumLog2'h0)) begin
            rdata1 <= `ZeroWord;
        end 
        else if ((raddr1 == waddr) && (we == `WriteEnable)) begin  //当同时有要写入数据和读出数据时就直接将数据传递给读端口，可避免raw情况之一
                    rdata1 <= wdata;
            end
        else if (re1 == `ReadEnable) begin
                rdata1 <= regs[raddr1];
            end
    end

    //读端口2
    always @(*) begin
        if ((rst == `RstEnable) || (re2 != `ReadEnable) || (raddr2 == `RegNumLog2'h0)) begin
            rdata2 <= `ZeroWord;
        end 
        else if ((raddr2 == waddr) && (we == `WriteEnable)) begin
                    rdata2 <= wdata;
            end
        else if (re2 == `ReadEnable) begin
                rdata2 <= regs[raddr2];
            end
    end

endmodule
